package com.zmp.kotlinnote.exchange

import android.app.Activity
import android.os.Handler
import android.os.Looper
import com.zmp.kotlinnote.entry.DMan
import com.zmp.kotlinnote.entry.DPerson
import com.zmp.kotlinnote.entry.Sun
import org.junit.Test


/**
 * TODO  扩展函数
 *
 * 1.扩展函数作用
 *
 * 能够扩展一个类的新功能而无需继承该类或使用像装饰者这样的任何类型的设计模式
 *
 *  2.创建扩展函数
 *
 *  声明一个扩展函数,需要被扩展的类型来作为他的前缀
 */
fun Any.log() {
    val stackTrace = Thread.currentThread().stackTrace
    val className = stackTrace[2].className
    val fileName = stackTrace[2].fileName
    val lineNumber = stackTrace[2].lineNumber
    val methodName = stackTrace[2].methodName

    println("$fileName:$methodName:$lineNumber->: ${this}")



}

val Any.person: DPerson by lazy {
    DPerson()
}

var jump = fun DPerson.(int: Int) {
    "jump".log()
    this.log()
}

fun DPerson.Companion.jump() {
    "Companion.jump".log()
}

fun DPerson.work() {
    "搬砖".log()
}

private fun DPerson.learn() {
    "学习kotlin".log()
}


class D2_2 {
    @Test
    fun main() {

        (0xF0.toByte().toInt() and 0xFF).log()


//        DPerson().jump(2)
//        DPerson().work()
//        DPerson.jump()
//        jump(DPerson(), 2)

        val s = "a"
        val personLog = s.person
        personLog.log()
        personLog.log()
        s.person.log()
        s.person.log()
    }
}


/**
 * TODO  扩展属性  幕后字段（field）是无效的
 * 由于扩展没有实际的将成员插入类中，因此对扩展属性来说幕后字段是无效的
 */

/**
 * val 不能有set方法 但对get没有约束
 */
val DPerson.weight: Int
    get() = this.age * 433


var DMan.score: Int
    get() = this.age * 20
    set(value) {
        age = value / 20
    }

/**
 *
 * 3.这意味着这些函数的分发对于分发接收者类型是虚拟的，但对于扩展接收者类型是静态的
 *
 * 扩展声明所在的类的实例称为 分发接收者，扩展方法 调用所在的接收者类型的实例称为 扩展接收者
 *
 * 1.扩展函数是由函数调用所在的表达式的类型来决定的, 而不是由表达式运行时求值结果决定的
 * 2.扩展函数是可以被继承覆盖的--针对class
 */

fun DMan.work() {
    jump()
    println("敲代码")
}

/**
 * 官方案例：
 */
class D2_3 {
    @Test
    fun main() {
        C().caller(D()) //11
        C().caller(D1())//11
        C1().caller(D())//
        C1().caller(D1())

        println()
//
//        C3().caller(D())
//        C3().caller(D1())
//        C4().caller(D())
//        C4().caller(D1())
        Sun.name
    }
}

/**
 * 单例类 扩展函数
 */
fun Sun.move() {
    "sun move".log()
}

class D2_4 {
    @Test
    fun main() {
        Sun.name.log()
        Sun.move()
    }
}


